package top.kaoshanji.p2ch21a;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

/**
 * 代码清单-p2ch21a-560页a：基于反射实现简单通用的序列化和反序列化的示例
 * author kaoshanji
 * ^_^
 * create time 2025/2/28 17:17
 */
public class SimpleMapper {

    // 将对象 obj 转换为字符串
    public static String toString(Object obj) {

        try {
            Class<?> cls = obj.getClass();
            StringBuilder sb = new StringBuilder();
            sb.append(cls.getName()).append("\n");

            for (Field field: cls.getDeclaredFields()) {
                if (!field.isAccessible()) {
                    field.setAccessible(true);
                }
                sb.append(field.getName()).append("=").append(field.get(obj).toString()).append("\n");
            }

            return sb.toString();
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }

    }

    // 将字符串 str 转换为对象
    public static Object fromString(String str) {
        try {
            String[] lines = str.split("\n");
            if (lines.length < 1) {
                throw new IllegalArgumentException(str);
            }

            Class<?> cls = Class.forName(lines[0]);
            Object obj = cls.newInstance();

            if (lines.length > 1) {
                for (int i = 1; i < lines.length; i++) {
                    String[] fv = lines[i].split("=");
                    if (fv.length != 2) {
                        throw new IllegalArgumentException(lines[i]);
                    }

                    Field field = cls.getDeclaredField(fv[0]);
                    if (!field.isAccessible()) {
                        field.setAccessible(true);
                    }

                    setFieldValue(field, obj, fv[1]);

                }
            }

            return obj;

        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    private static void setFieldValue(Field field, Object obj, String value) throws Exception {

        Class<?> type = field.getType(); // 字段类型
        if (type == int.class) {
            field.setInt(obj, Integer.parseInt(value));
        } else if (type == byte.class) {
            field.setByte(obj, Byte.parseByte(value));
        } else if (type == short.class) {
            field.setShort(obj, Short.parseShort(value));
        } else if (type == long.class) {
            field.setLong(obj, Long.parseLong(value));
        } else if (type == float.class) {
            field.setFloat(obj, Float.parseFloat(value));
        } else if (type == double.class) {
            field.setDouble(obj, Double.parseDouble(value));
        } else if (type == char.class) {
            field.setChar(obj, value.charAt(0));
        } else if (type == boolean.class) {
            field.setBoolean(obj, Boolean.parseBoolean(value));
        } else if (type == String.class) {
            field.set(obj, value);
        } else {
            Constructor<?> ctor = type.getConstructor(new Class[]{String.class});
            field.set(obj, ctor.newInstance(value));
        }

    }


}
